Sub Dev 讨论 | Pallet 之间动态调用方法最新进展
一块链习是首家区块链技术学习社区,提供最系统的区块链技术课程学习,定期出品有深度的技术观察 + 评论。
《从0到一学会Substrate 区块链应用开发》由一块链习和Parity官方联合出品,专为区块链技术爱好者量身打造,并由 王大锤,陈锡亮,孙凯超,朱振明四位老师联合授课。
目前第一期课程已经进行到第三周,同学们会在班级群讨论学习中遇到的难题或不解。另外每周日上午 10 点,都会进行课程内容知识拓展——作业点评会和在线答疑。
现在将第三周班级群日常优质的讨论内容和胡键助教对第四、五课的作业点评分享给大家。
01
昊暠skyh-学员:substrate 使用rpc调用extrincs的例子或者文档有吗?
陈锡亮-讲师:
https://polkadot.js.org/api/substrate/rpc.html#submitandwatchextrinsic-extrinsic-extrinsic-extrinsicstatus
polkadot apps检查元素看network ws可以看具体怎么交互的。
02
Lam007-学员:
程剑宇 - 助教:这是parathread,parachain是常连的,通过slot竞拍。parathread是需要时连,按使用付费。
Lam007-学员:就是说relay chain连接点是有数量限制的,而parachains通过竞拍(付费),成为常连chain。
而relay chain 也会预留一些连接点给parathread,以便parathread有需要时付费连接。
程剑宇 - 助教:是的。
Lam007-学员:任何parachain都能成为一个relaychain,但是它可以选择免费接入,是吗?
程剑宇 - 助教:relaychain只有一个。
Lam007-学员:relay chain外围的parachain也可以再接一层parachain,那么第一层的parachain就可以作为外一层parachain的relay chain。
程剑宇 - 助教:嗯sub relay吧,不过感觉这个还要挺久的。
03
红军大叔-学员:
这块metadata和balance模块下的讲解, 提到calls对应到decl_module下的const 常量, 听不懂, 想表达什么意思呢?现在大致理解的是:模块宏下面的内容, 会暴露给metadata, metadata的作用是给前端使用?
陈威-学员:
pub fn transfer(
origin,
dest: <T::Lookup as StaticLookup>::Source,
#[compact] value: T::Balance
)
这些信息和上面的注释会放到metadata的call里面。const ExistentialDeposit: T::Balance = T::ExistentialDeposit::get();
这是常量, 不放到calls, 放到constants。
每个模块的元素都集中到metadata, 前端就可以, 通过这个知道, 每个模块的calls, errors, constants, events
比如一个错误出现, 前端扫描块时只能得到一个序号, 根据metadata转换后可以得到err的描述, 和err的名字.
// retrieve and log the complete metadata of your node
let a = await api.rpc.state.getMetadata();
a = a.toJSON();
console.log(JSON.stringify(a, null, 2));
陈锡亮-讲师:decl_module里面除了calls也可以放constants,之所以用宏搞的这么麻烦主要就是为了可以自动生成metadata暴露给前端,前端可以通过这些信息知道如何于链交互。
04
红军大叔-学员:判断溢出,生产环境有没有类似atom的原子方式保护?比如上述代码方式, 存不存在并发引起的问题?
WJY-学员:怎么会并发呢?
陈威-学员:原子操作是多线程用的。并且不是处理溢出的。区块链里面是顺序处理交易。
WJY-学员:多线程现在还在幻想当中,现在都是顺序处理 所以都是慢慢累加。
廖师虎-学员:事件不会乱序吗?不同节点的事务池,事务条目可能不同
WJY-学员:顺序不用管啊 ,我觉得合理就打包,想象它就是一台机器的工作。加入链中的区块是需要进一步共识的 ,最终都一样,就是不同节点你有不同出块可以 但是没关系 最终我们会达成共识用哪个。
红军大叔-学员:这么说, 区块链在并发方面其实倒是简单了?回顾下, 好像也确实只有在dag的时候提到并发, 其他是都是顺序的。
WJY-学员:是的,现在几乎所有都是副本模式嘛 所有机器干同样工作。不是竞争关系。
05
没得-学员:
有没有大哥知道这个怎么实现啊?用range和迭代器实现阶乘。
洋芋-助教:这个试下呢,
https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.product
06
raindust-学员:请问pallet之间有什么方法可以互相调用吗?我目前所知的方式只有使用一个pallet的Trait继承另一个pallet的Trait。
陈威-学员:关联类型,或者从你的Trait的泛型参数传入。
陈锡亮-讲师:有什么需求你要动态调用,可以参考pallet-scheduler。
raindust-学员:我在想有没有可能在不同的pallet的下层假设一个message bus以增加节点的可伸缩性,所以想先了解一下相关的原理。
陈锡亮-讲师:polkadot 目前正常尝试实现一套新的框架用于xcmp,其中也有一套message bus的设计,未来也可能也会提供给substrate使用。可以听听看 https://www.crowdcast.io/e/polkadefi-conference/1
陈威-学员:你要pallet发出消息,其他pallet接收?
raindust-学员:是的,类似于这样,如果这样可以实现,就可以了在中间放一个消息队列了,如果是加了message bus就会希望一个小的集群代表一个节点工作,我是想让substrate应用在联盟链方向。
第四课
题目要求
算出指定档案的 hash + 不超过 255 长度的 note 将以上内容以 signed tx 方式传给 Substrate 保存
增加 note 的最大长度定义 仿造原有的 proof 的定义,在其基础上增加 note 字段 仿造 create_claim 函数,增加 create_claim_with_note,增加 note 参数,以及相应的长度验证逻辑,其余照旧。 事件复用之前的 ClaimCreated 就好了。
create_claim_with_note 中传入的参数为 Option\ ,这个比较符合实际情况,因为用户确实有可能不输入 note。 在 map 中考虑了时戳,这样整个结构就变成了下面的样子,更加人性化。
ProofHash2Detail: map hasher(blake2_128_concat)Vec<u8>=>(T::AccountId, T::BlockNumber, T::Moment,Option<Vec<u8>>);
增加 note 的输入框,以及配套的状态设置函数。 添加事件监听函数,以便在成功创建之后显示相应信息。 修改提交部分的代码,将其替换成 node 中相应的实现函数,以及在输入中加入 note 参数。
向 node 发起 extrinc 的格式:api.tx.\ .\ \>,若是查询的话,则 api.tx => api.query。 \>
比如:api.tx.poeModule.createClaimWithNote(hasher, comment).signAndSend(alice)
const api = await connect();
let content = fs.readFileSync(filePath, 'utf-8');
let hasher = blake2AsHex(content);
const keyring = new Keyring({ type: 'sr25519' });
const alice = keyring.addFromUri('//Alice');
const hash = await api.tx.poeModule.createClaimWithNote(hasher, comment).signAndSend(alice);
console.log('done with hash: ', hash);
在创建的同时,将其记录到另一个以 account id 为 key 的 map 中,其 value 则是对应的输入。
增加一个 map 用来记录相关信息 在上面的 create_claim_with_note 中记录其输入
fn random_value(sender: &T::AccountId) -> [u8; 16] { let payload = ( T::Randomness::random_seed(), &sender, <frame_system::Module<T>>::extrinsic_index(),); payload.using_encoded(blake2_128)}
fn insert_kitty(owner:&T::AccountId, kitty_id: T::KittyIndex, kitty:Kitty){
Kitties::<T>::insert(kitty_id, kitty);
KittiesCount::<T>::put(kitty_id +1.into());
let user_kitties_id =Self::owned_kitties_count(&owner);
// 注意这里的是通过 account_id 和 索引来得到对应的 kitty id,故如此
<OwnedKitties<T>>::insert((owner.clone(), user_kitties_id), kitty_id);
<OwnedKittiesCount<T>>::insert(owner, user_kitties_id +1);
}
Self::insert_kitty(sender, kitty_id, kitty);
这是由一块链习和Parity出品,专为区块链技术爱好者量身打造的Substrate技术开发体验课。
课程采用班级群+小组学习制模式进行。由课程导师+助教+班长共同为用户提供服务,采用 15 人左右小组学习制,每位助教定向辅导一个小组并进行定向作业辅导、答疑等,确保更好的学习效果。
除了四位讲师,还有6位助教加入课程。所有助教均有一线区块链公司技术相关背景,并有Substrate技术实战经验,确保每一位开发者都能够得到更专业有效的指导。
第一期课程报名开启一周,100个席位全部抢占完。
第二期课程报名通道提前开放,已经有开发者率先占座。席位有限,报名请抓紧!
欢迎扫码了解更多和课程报名!
扫码关注公众号,回复“1”加入开发者社群